--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / frontend / js / healthMemoryWarning.js
Displaying Raw • Download
meshchatx/src/frontend/js/healthMemoryWarning.js 9f75e3db181925ddd253f7fb231af81f9fb8c013 (9f75e3db) Text, 4.65 KB
T8b949e// SPDX-License-Identifier: 0BSD
T8b949e/**
* Session-scoped high-memory warning toast helpers.
*
* Host RAM pressure arrives via WebSocket health_warning (kind memory_low).
* Client JS heap pressure is sampled locally when performance.memory exists.
* Toast is sticky (duration 0) and shown at most once per pressure episode.
*/
Tff7b72export Tff7b72const Te6edf3MEMORY_WARNING_TOAST_KEY Tff7b72= Ta5d6ff"health-memory-warning"Tb4b4b4;
Tff7b72export Tff7b72const Te6edf3MEMORY_WARNING_MESSAGE_KEY Tff7b72= Ta5d6ff"app.memory_pressure_warning"Tb4b4b4;
Tff7b72export Tff7b72const Te6edf3CLIENT_HEAP_RATIO_THRESHOLD Tff7b72= T79c0ff0.85Tb4b4b4;
Tff7b72export Tff7b72const Te6edf3CLIENT_HEAP_CONSECUTIVE_NEEDED Tff7b72= T79c0ff2Tb4b4b4;
Tff7b72export Tff7b72const Te6edf3CLIENT_HEAP_SAMPLE_INTERVAL_MS Tff7b72= T79c0ff30000Tb4b4b4;
Tff7b72let Te6edf3dismissedThisEpisode Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72let Te6edf3toastVisible Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72let Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72export Tff7b72function Te6edf3resetMemoryWarningStateForTestsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3dismissedThisEpisode Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3toastVisible Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3warningDataFromPayloadTb4b4b4(Te6edf3payloadTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3payload Tff7b72|| Tff7b72typeof Te6edf3payload Tff7b72!== Ta5d6ff"object"Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72nullTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3data Tff7b72&& Tff7b72typeof Te6edf3payloadTb4b4b4.Te6edf3data Tff7b72=== Ta5d6ff"object"Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3payloadTb4b4b4.Te6edf3dataTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3payloadTb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {unknown} payload
* @returns {boolean}
*/
Tff7b72export Tff7b72function Te6edf3isMemoryHealthWarningPayloadTb4b4b4(Te6edf3payloadTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3data Tff7b72= Te6edf3warningDataFromPayloadTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657BooleanTb4b4b4(Te6edf3data Tff7b72&& Te6edf3dataTb4b4b4.Te6edf3kind Tff7b72=== Ta5d6ff"memory_low"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {unknown} payload
* @returns {boolean}
*/
Tff7b72export Tff7b72function Te6edf3isMemoryRecoveredPayloadTb4b4b4(Te6edf3payloadTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3data Tff7b72= Te6edf3warningDataFromPayloadTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657BooleanTb4b4b4(Te6edf3data Tff7b72&& Te6edf3dataTb4b4b4.Te6edf3kind Tff7b72=== Ta5d6ff"memory_recovered"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {{ fromHealthWs?: boolean, fromClientHeap?: boolean }} options
* @returns {boolean}
*/
Tff7b72export Tff7b72function Te6edf3shouldShowMemoryWarningToastTb4b4b4(Te6edf3options Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dismissedThisEpisode Tff7b72|| Te6edf3toastVisibleTb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657BooleanTb4b4b4(Te6edf3optionsTb4b4b4.Te6edf3fromHealthWs Tff7b72|| Te6edf3optionsTb4b4b4.Te6edf3fromClientHeapTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3markMemoryWarningShownTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3toastVisible Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3markMemoryWarningDismissedTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3toastVisible Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3dismissedThisEpisode Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3markMemoryWarningRecoveredTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3dismissedThisEpisode Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3toastVisible Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {{ jsHeapSizeLimit?: number, usedJSHeapSize?: number } | null | undefined} memoryInfo
* @returns {{ shouldWarn: boolean, reason: string, ratio?: number, consecutive?: number }}
*/
Tff7b72export Tff7b72function Te6edf3evaluateClientHeapSampleTb4b4b4(Te6edf3memoryInfoTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3memoryInfo Tff7b72|| Tff7b72typeof Te6edf3memoryInfoTb4b4b4.Te6edf3jsHeapSizeLimit Tff7b72!== Ta5d6ff"number" Tff7b72|| Te6edf3memoryInfoTb4b4b4.Te6edf3jsHeapSizeLimit Tff7b72<= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72return Tb4b4b4{ Te6edf3shouldWarnTff7b72: Tff7b72falseTb4b4b4, Te6edf3reasonTff7b72: Ta5d6ff"unavailable" Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3used Tff7b72= Te6edf3memoryInfoTb4b4b4.Te6edf3usedJSHeapSizeTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72typeof Te6edf3used Tff7b72!== Ta5d6ff"number" Tff7b72|| Tff7b72!Tffa657NumberTb4b4b4.Tffa657isFiniteTb4b4b4(Te6edf3usedTb4b4b4) Tff7b72|| Te6edf3used Tff7b72< T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72return Tb4b4b4{ Te6edf3shouldWarnTff7b72: Tff7b72falseTb4b4b4, Te6edf3reasonTff7b72: Ta5d6ff"invalid" Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3ratio Tff7b72= Te6edf3used Tff7b72/ Te6edf3memoryInfoTb4b4b4.Te6edf3jsHeapSizeLimitTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3ratio Tff7b72< Te6edf3CLIENT_HEAP_RATIO_THRESHOLDTb4b4b4) Tb4b4b4{
Te6edf3consecutiveHighHeap Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72return Tb4b4b4{ Te6edf3shouldWarnTff7b72: Tff7b72falseTb4b4b4, Te6edf3reasonTff7b72: Ta5d6ff"below_threshold"Tb4b4b4, Te6edf3ratio Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Te6edf3consecutiveHighHeap Tff7b72+= T79c0ff1Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3consecutiveHighHeap Tff7b72< Te6edf3CLIENT_HEAP_CONSECUTIVE_NEEDEDTb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4{
Te6edf3shouldWarnTff7b72: Tff7b72falseTb4b4b4,
Te6edf3reasonTff7b72: Ta5d6ff"need_consecutive"Tb4b4b4,
Te6edf3ratioTb4b4b4,
Te6edf3consecutiveTff7b72: Te6edf3consecutiveHighHeapTb4b4b4,
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72return Tb4b4b4{
Te6edf3shouldWarnTff7b72: Tff7b72trueTb4b4b4,
Te6edf3reasonTff7b72: Ta5d6ff"high_heap"Tb4b4b4,
Te6edf3ratioTb4b4b4,
Te6edf3consecutiveTff7b72: Te6edf3consecutiveHighHeapTb4b4b4,
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {{ warning: (message: string, duration?: number, key?: string | null) => void }} toastUtils
* @param {{ fromHealthWs?: boolean, fromClientHeap?: boolean }} options
* @returns {boolean} true when a toast was shown
*/
Tff7b72export Tff7b72function Te6edf3showMemoryWarningToastIfNeededTb4b4b4(Te6edf3toastUtilsTb4b4b4, Te6edf3options Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3shouldShowMemoryWarningToastTb4b4b4(Te6edf3optionsTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3toastUtils Tff7b72|| Tff7b72typeof Te6edf3toastUtilsTb4b4b4.Te6edf3warning Tff7b72!== Ta5d6ff"function"Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3toastUtilsTb4b4b4.Te6edf3warningTb4b4b4(Te6edf3MEMORY_WARNING_MESSAGE_KEYTb4b4b4, T79c0ff0Tb4b4b4, Te6edf3MEMORY_WARNING_TOAST_KEYTb4b4b4)Tb4b4b4;
Te6edf3markMemoryWarningShownTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
T8b949e/**
* @param {unknown} payload
* @param {{ warning: (message: string, duration?: number, key?: string | null) => void }} toastUtils
* @returns {"shown" | "recovered" | "ignored"}
*/
Tff7b72export Tff7b72function Te6edf3handleHealthWarningPayloadTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3toastUtilsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3isMemoryRecoveredPayloadTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3markMemoryWarningRecoveredTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Ta5d6ff"recovered"Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isMemoryHealthWarningPayloadTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"ignored"Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3showMemoryWarningToastIfNeededTb4b4b4(Te6edf3toastUtilsTb4b4b4, Tb4b4b4{ Te6edf3fromHealthWsTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4) Tff7b72? Ta5d6ff"shown" Tff7b72: Ta5d6ff"ignored"Tb4b4b4;
Tb4b4b4}
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────